home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HPAVC
/
HPAVC CD-ROM.iso
/
WD_SRC.ZIP
/
BSP_GEN
/
IO.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1995-01-12
|
15KB
|
581 lines
#include "..\Source\LastWolf.hpp"
extern DWORD nSplits, nBalancesChosen, nSplitsChosen;
extern WORD nOriginalPoints, nOriginalLines;
extern WORD nExactIntersections;
BOOL ProcessCommandLine( int argc, char *argv[], BspCommandLine *pToProcess )
{
if( argc < 4 )
return FALSE;
pToProcess->bDoomLevel = FALSE;
pToProcess->pFilename = argv[1];
pToProcess->pOutputFile = argv[2];
pToProcess->balance = (WORD)atoi( argv[3] );
if( argc >= 5 )
{
pToProcess->bDoomLevel = TRUE;
pToProcess->pLevelName = argv[4];
if( argv[5][0] == '1' )
{
pToProcess->bLoadDoomTextures = FALSE;
pToProcess->pTextureWadName = NULL;
}
else
{
pToProcess->bLoadDoomTextures = TRUE;
pToProcess->pTextureWadName = argv[5];
}
if( argc > 6 )
videoMode = atoi(argv[6]);
}
return TRUE;
}
BOOL LoadTextData( BYTE *pFilename, CLineArray *pLines, CPointArray *pPoints )
{
FILE *fpText;
WORD nLines, nPoints;
WORD curPoint, curLine;
// Used when reading Lines in.
WORD iPoint1, iPoint2;
CPoint *pCurPoint;
CLine *pCurLine;
fpText = fopen( pFilename, "r" );
if( fpText == NULL )
return FALSE;
// Get the number of Points and Lines.
SkipComments(fpText);
fscanf( fpText, "%hd", &nPoints );
SkipComments(fpText);
fscanf( fpText, "%hd", &nLines );
// Allocate the memory for the arrays.
pLines->SetSize(nLines);
pPoints->SetSize(nPoints);
pLines->AllocateElements();
pPoints->AllocateElements();
// Read in all the Points.
for( curPoint=0; curPoint < nPoints; curPoint++ )
{
pCurPoint = pPoints->GetPoint(curPoint);
SkipComments(fpText);
fscanf( fpText, "%hd , %hd", &pCurPoint->localX, &pCurPoint->localY );
}
// Read in all the Lines.
for( curLine=0; curLine < nLines; curLine++ )
{
pCurLine = pLines->GetLine(curLine);
SkipComments(fpText);
fscanf( fpText, "%hd , %hd", &iPoint1, &iPoint2 );
pCurLine->pPoint1 = pPoints->GetPoint(iPoint1);
pCurLine->pPoint2 = pPoints->GetPoint(iPoint2);
SkipComments(fpText);
fscanf( fpText, "%hd , %hd", &pCurLine->idLeftTex, &pCurLine->idRightTex );
}
fclose(fpText);
return TRUE;
}
BOOL OutputTextData( CLine *pRoot, char *pFilename, CLineArray *pLines, CPointArray *pPoints )
{
CPoint *pCurPoint;
CLine *pCurLine;
Index i, iPoint1, iPoint2, iLeft, iRight;
WORD nInternal, nExternal;
FILE *fp;
float BalanceToSplit;
pRoot=pRoot;
fp = fopen( pFilename, "w" );
if( fp == NULL )
return FALSE;
BalanceToSplit = (float)nBalancesChosen / (float)nSplitsChosen;
fprintf(fp, "Ratio of best balances to splits chosen:\t%f\n", BalanceToSplit);
fprintf(fp, "\nRoot Line:\t\t%d\n", pLines->GetIndexFromPointer(pRoot));
NodeInfo( pLines, &nInternal, &nExternal );
fprintf(fp, "Internal nodes:\t\t%d\n", nInternal);
fprintf(fp, "External nodes:\t\t%d\n", nExternal);
fprintf(fp, "\nExact intersections: %d\n", nExactIntersections);
fprintf(fp, "\nOriginal number of Points:\t\t%d", nOriginalPoints);
fprintf(fp, "\nFinished number of Points:\t\t%d", pPoints->NumElements());
fprintf(fp, "\nRatio of finished to original:\t\t%f\n", (float)pPoints->NumElements() / (float)nOriginalPoints );
fprintf(fp, "\nOriginal number of Lines:\t\t%d", nOriginalLines);
fprintf(fp, "\nFinished number of Lines:\t\t%d", pLines->NumElements());
fprintf(fp, "\nRatio of finished to original:\t\t%f\n", (float)pLines->NumElements() / (float)nOriginalLines );
// Output all the Points.
fprintf(fp, "\n\nPoints\n-------------\n");
for( i=0; i < pPoints->NumElements(); i++ )
{
pCurPoint = pPoints->GetPoint(i);
fprintf( fp, "\nPoint %d - (%d, %d)", i, pCurPoint->localX, pCurPoint->localY );
}
// Output all the Lines.
fprintf( fp, "\n\n\nLines\n-------------\n" );
for( i=0; i < pLines->NumElements(); i++ )
{
pCurLine = pLines->GetLine(i);
iPoint1 = pPoints->GetIndexFromPointer( pCurLine->pPoint1 );
iPoint2 = pPoints->GetIndexFromPointer( pCurLine->pPoint2 );
iLeft = pLines->GetIndexFromPointer( pCurLine->pLeft );
iRight = pLines->GetIndexFromPointer( pCurLine->pRight );
fprintf( fp, "\nLine %d", i );
fprintf( fp, "\nPoints - (%d, %d), (Left: %d, Right: %d)\n", iPoint1, iPoint2, iLeft, iRight );
}
fclose(fp);
return TRUE;
}
void NodeInfo( CLineArray *pLineList, WORD *pNInternal, WORD *pNExternal )
{
WORD i;
*pNInternal=*pNExternal=0;
for( i=0; i < pLineList->NumElements(); i++ )
{
if( pLineList->GetLine(i)->pLeft == NULL )
++*pNExternal;
else
++*pNInternal;
if( pLineList->GetLine(i)->pRight == NULL )
++*pNExternal;
else
++*pNInternal;
}
}
void SkipComments(FILE *fp)
{
char testChar;
while(1)
{
testChar = (char)fgetc(fp);
if( isdigit(testChar) )
break;
}
fseek( fp, -1, SEEK_CUR );
}
//////////////////////////////////////////////////
// GRAPHICAL DISPLAY
//////////////////////////////////////////////////
#ifdef DISPLAY_GRAPHICAL
BOOL DisplayGraphicalData( CLineArray *pLines, CPointArray *pPoints )
{
WORD lowestX=32767, lowestY=32767, highestX=0, highestY=0;
WORD personX=0, personY=0;
WORD xOffset=0, yOffset=0;
WORD offsetInc = 4;
Fixed scale = FIXED_ONE;
WORD i;
CPoint *pCurPt;
// Find the point with the least X and make the X offset that..
for( i=0; i < pPoints->NumElements(); i++ )
{
pCurPt = pPoints->GetPoint(i);
lowestX = LEAST(lowestX,pCurPt->localX);
lowestY = LEAST(lowestY,pCurPt->localY);
highestX = GREATEST(highestX,pCurPt->localX);
highestY = GREATEST(highestY,pCurPt->localY);
}
#ifdef SCREEN_ON
s_Init();
#endif
while(1)
{
if( kbhit() )
{
switch( toupper(getch()) )
{
case 'Q':
#ifdef SCREEN_ON
s_UnInit();
#endif
return TRUE;
case 'W':
personY -= offsetInc;
break;
case 'A':
personX -= offsetInc;
break;
case 'S':
personY += offsetInc;
break;
case 'D':
personX += offsetInc;
break;
case 'R':
scale += FIXED_ONE / 30;
offsetInc -= 10;
break;
case 'F':
if( scale > ((FIXED_ONE / 30) * 2) )
scale -= FIXED_ONE / 30;
offsetInc += 10;
break;
}
}
xOffset = (WORD)R_UNFIX(personX*scale);
yOffset = (WORD)R_UNFIX(personY*scale);
#ifdef SCREEN_ON
s_Clear(0);
#endif
Draw2DEnvironment( pLines, pPoints, xOffset, yOffset, scale, s_Width, s_Height );
#ifdef SCREEN_ON
s_Draw();
#endif
}
}
void DrawLine( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
{
WORD numPixels;
WORD i;
Fixed curX, curY, xInc, yInc;
// Test if it's off the screen so we might not have to draw it.
if( (x1 < 0 || x1 >= s_Width) && (y1 < 0 || y1 >= s_Height) &&
(x2 < 0 || x2 >= s_Width) && (y2 < 0 || y2 >= s_Height) )
return;
if( ABS(x2-x1) > ABS(y2-y1) )
numPixels = (WORD)ABS(x2-x1);
else
numPixels = (WORD)ABS(y2-y1);
if( numPixels < 2 )
return;
curX = FIX(x1);
curY = FIX(y1);
xInc = FIX(x2-x1) / numPixels;
yInc = FIX(y2-y1) / numPixels;
for( i=0; i < numPixels; i++ )
{
#ifdef SCREEN_ON
s_SetPixel( (WORD)UNFIX(curX), (WORD)UNFIX(curY), 24 );
#endif
curX += xInc;
curY += yInc;
}
}
#endif
//////////////////////////////////////////////////
// DOOM FILE READING
//////////////////////////////////////////////////
BOOL LoadDoomLevel( BYTE *pFilename, BYTE *pLevelName, CLineArray *pLineArray, CPointArray *pPointArray, BOOL bLoadTextures, BYTE *pTextureWadName )
{
WORD nVertices, nLinedefs, nSidedefs, i;
DoomVertex *pDoomVertices;
DoomLinedef *pDoomLinedefs, *pCurLinedef;
DirEntry dirLevel, dirVertices, dirLinedefs, dirSidedefs;
DWORD directoryPos, levelPos;
MFile wadFile;
// Stuff for loading textures.
MFile textureWad;
DWORD textureDirectory;
DoomSidedef *pDoomSidedefs, *pCurSidedef;
DoomSidedef tempSky;
if( wadFile.fio_OpenSource( pFilename, 'R' ) == FALSE )
return FALSE;
// Get the position of the directory.
wadFile.fio_Seek( 8 );
wadFile.fio_Read( &directoryPos, 4 );
levelPos = GetDirEntry( &wadFile, pLevelName, directoryPos, &dirLevel );
// Get the directory entries for Vertices and Linedefs.
GetDirEntry( &wadFile, "VERTEXES", levelPos, &dirVertices );
GetDirEntry( &wadFile, "LINEDEFS", levelPos, &dirLinedefs );
GetDirEntry( &wadFile, "SIDEDEFS", levelPos, &dirSidedefs );
// Read in all the Vertices and translate them to Points.
nVertices = (WORD)(dirVertices.resLength / sizeof(DoomVertex));
pPointArray->SetSize(nVertices);
pPointArray->AllocateElements();
pDoomVertices = new DoomVertex[nVertices];
wadFile.fio_Seek( dirVertices.resPos );
wadFile.fio_Read( pDoomVertices, dirVertices.resLength );
for( i=0; i < nVertices; i++ )
{
pPointArray->GetPoint(i)->localX = (WORD)pDoomVertices[i].x;
pPointArray->GetPoint(i)->localY = (WORD)pDoomVertices[i].y;
}
delete pDoomVertices;
// Read in all the Linedefs and translate them to Points.
nLinedefs = (WORD)(dirLinedefs.resLength / sizeof(DoomLinedef));
pLineArray->SetSize(nLinedefs);
pLineArray->AllocateElements();
// Zero-init all the Lines.
for( i=0; i < nLinedefs; i++ )
memset( pLineArray->GetLine(i), 0, sizeof(CLine) );
pDoomLinedefs = new DoomLinedef[nLinedefs];
memset( pDoomLinedefs, 0, sizeof(DoomLinedef)*nLinedefs );
wadFile.fio_Seek( dirLinedefs.resPos );
wadFile.fio_Read( pDoomLinedefs, dirLinedefs.resLength );
if( bLoadTextures )
{
DirEntry dirPalette;
printf("Loading textures from %s.", pTextureWadName);
printf("\n");
if( textureWad.fio_OpenSource( pTextureWadName, 'R' ) == FALSE )
return FALSE;
// Get the position of the directory.
textureWad.fio_Seek( 8 );
textureWad.fio_Read( &textureDirectory, 4 );
// Initialize Doom texture loading module.
InitDoomTex( &textureWad, textureDirectory );
nSidedefs = (WORD)(dirSidedefs.resLength / sizeof(DoomSidedef));
pDoomSidedefs = new DoomSidedef[nSidedefs];
memset( pDoomSidedefs, 0, nSidedefs*sizeof(DoomSidedef) );
// Read in the SideDefs.
wadFile.fio_Seek( dirSidedefs.resPos );
wadFile.fio_Read( pDoomSidedefs, nSidedefs * sizeof(DoomSidedef) );
// Go through all the LineDefs and load their textures (from the SideDefs).
for( i=0; i < nLinedefs; i++ )
{
pCurLinedef = &pDoomLinedefs[i];
// Do the right Sidedef automatically .. all Doom Linedefs have one.
if( pCurLinedef->rightSidedef == -1 )
{
pLineArray->GetLine(i)->idRightTex = BAD_TEXTURE_ID;
}
else
{
pCurSidedef = &pDoomSidedefs[ pCurLinedef->rightSidedef ];
pLineArray->GetLine(i)->idRightTex = LoadSidedefTexture( pCurSidedef, &textureWad, textureDirectory );
}
if( pCurLinedef->leftSidedef == -1 )
{
pLineArray->GetLine(i)->idLeftTex = BAD_TEXTURE_ID;
}
else
{
pCurSidedef = &pDoomSidedefs[ pCurLinedef->leftSidedef ];
pLineArray->GetLine(i)->idLeftTex = LoadSidedefTexture( pCurSidedef, &textureWad, textureDirectory );
}
}
// The WAD with the textures is assumed to have the palette..
// Read it and the palette maps in.
if( GetDirEntry( &textureWad, "PLAYPAL", textureDirectory, &dirPalette ) != -1 )
{
textureWad.fio_Seek( dirPalette.resPos );
textureWad.fio_Read( curLevel.palette, 768 );
for( i=0; i < 768; i++ )
curLevel.palette[i] = curLevel.palette[i] / 4;
}
#ifndef PALETTE_MAPS
if( GetDirEntry( &textureWad, "COLORMAP", textureDirectory, &dirPalette ) != -1 )
{
textureWad.fio_Seek( dirPalette.resPos );
nPaletteMaps = 32;
pPaletteMaps = new BYTE *[32];
for( i=0; i < 32; i++ )
{
pPaletteMaps[i] = new BYTE[256];
textureWad.fio_Read( pPaletteMaps[i], 256 );
}
textureWad.fio_Read( blackWhitePal, 256 );
}
#endif
// Read in the skies too.
sprintf( tempSky.normalTex, "SKY1" );
curLevel.idSky1 = LoadSidedefTexture( &tempSky, &textureWad, textureDirectory );
sprintf( tempSky.normalTex, "SKY2" );
curLevel.idSky2= LoadSidedefTexture( &tempSky, &textureWad, textureDirectory );
sprintf( tempSky.normalTex, "SKY3" );
curLevel.idSky3= LoadSidedefTexture( &tempSky, &textureWad, textureDirectory );
curLevel.idCurSky = curLevel.idSky1;
// UnInitialize Doom texture loading module.
UnInitDoomTex();
textureWad.fio_CloseSource();
delete pDoomSidedefs;
}
for( i=0; i < nLinedefs; i++ )
{
pLineArray->GetLine(i)->pPoint1 = pPointArray->GetPoint( pDoomLinedefs[i].iFromVert );
pLineArray->GetLine(i)->pPoint2 = pPointArray->GetPoint( pDoomLinedefs[i].iToVert );
pLineArray->GetLine(i)->wallColor = (TextureID)rand() % 255;
}
delete pDoomLinedefs;
// Done .. clean up and return.
wadFile.fio_CloseSource();
return TRUE;
}
DWORD GetDirEntry( MFile *pWadFile, char *pEntryName, DWORD startSearchAt, DirEntry *pEntry )
{
WORD i, nEntries;
nEntries = (pWadFile->fio_FileLength() - startSearchAt) / sizeof(DirEntry);
pWadFile->fio_Seek( startSearchAt );
for( i=0; i < nEntries; i++ )
{
pWadFile->fio_Read( pEntry, sizeof(DirEntry) );
if( strncmp( pEntry->resName, pEntryName, 8 ) == 0 )
return pWadFile->fio_GetPosition();
}
return -1;
}